﻿using System.Reactive.Concurrency;
using System.Reactive.Linq;
using Microsoft.Reactive.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Rxx.UnitTests.Reactive
{
	[TestClass]
	public class IntrospectiveTests : RxxTests
	{
		/// <summary>
		/// Origin of unit test: 
		/// http://social.msdn.microsoft.com/Forums/en-US/rx/thread/87153e99-3a8b-4515-b743-33983ccb9138/
		/// </summary>
		[TestMethod]
		public void SampleIntrospective()
		{
			var scheduler = new TestScheduler();

			var source = scheduler.CreateHotObservable(
				OnNext(110, "A"),
				OnNext(120, "B"),
				OnNext(130, "C"),
				OnNext(140, "D"),
				// ... delay ...
				OnNext(180, "E"),
				OnNext(190, "F"),
				OnNext(200, "G"), OnNext(201, "H"), OnNext(202, "I"), // burst
				// ... delay ...
				OnNext(250, "J"),
				// ... delay ...
				OnNext(300, "K"), OnNext(302, "L"), OnNext(304, "M"), // burst
				// complete
				OnCompleted<string>(304),
				OnNext(305, "N")
			);

			var sampledSource = source.SampleIntrospective(scheduler)
				.Do(_ =>
				{
					var isEnabled = typeof(VirtualTimeSchedulerBase<long, long>).GetProperty("IsEnabled");

					// AdvanceBy is ignored unless IsEnabled is temporarily set to false
					isEnabled.SetValue(scheduler, false, null);

					// simulate a blocking observer
					scheduler.AdvanceBy(15);

					isEnabled.SetValue(scheduler, true, null);
				});

			AssertEqual(
				scheduler.Start(() => sampledSource, created: 0, subscribed: 0, disposed: 10000).Messages,
				OnNext(126, "A"),
				OnNext(142, "B"),
				// skipping "C"
				OnNext(158, "D"),
				OnNext(196, "E"),
				OnNext(212, "F"),
				// skipping "G"
				// skipping "H"
				OnNext(228, "I"),
				OnNext(266, "J"),
				OnNext(316, "K"),
				// skipping "L", "M"
				OnCompleted<string>(316));
		}
	}
}